/*
 * 手机轮播图插件
 * Author: rguanghui.stupid@gmail.com, rguanghui.sinaapp.com
 * Update: 2014.08.30
 * Verson: 1.0
 * @param container {string|object} 轮播图外层的dom或者id
 * @param config {object} 需要的一些参数
 * config.ul        譬如ul，这是为了可以兼容其他的html结构。
 * config.li        譬如li，这是为了可以兼容其他的html结构。
 * config.autoTime  自动播放的间隔，单位是秒。默认为5秒，设置为0则不进行自动播放
 */

define(function(){

  "use strict";

  var _elementStyle = document.createElement("div").style;

  var _vendor = function() {
    var vendors = ["t", "webkitT", "msT", "mozT", "oT"],
        transform,
        i = 0,
        l = vendors.length;
    for( ; i < l; i++) {
      transform = vendors[i] + "ransform";
      if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length - 1);
    };
  }();

  function _prefixStyle(style) {
    if ( _vendor === false ) return false;
    if ( _vendor === "" ) return style;
    return _vendor + style.charAt(0).toUpperCase() + style.substr(1);
  };

  var _support = {
    transform3d: ( _prefixStyle("perspective") in _elementStyle ),
    touch: ( "ontouchstart" in window )
  };

  var _desktopEvents = ["mousedown", "mousemove", "mouseup", "mouseout"];

  var _e = {
    start: _support.touch ? "touchstart" : _desktopEvents[0],
    move: _support.touch ? "touchmove" : _desktopEvents[1],
    end: _support.touch ? "touchend" : _desktopEvents[2],
    cancel: _support.touche ? "touchcancel" : _desktopEvents[3]
  };

  function getTranslate(x) {
    return _support.transform3d ? "translate3d(" + x + "px, 0, 0)" : "translate(" + x + "px, 0)";
  };

  function getEvent(e) {
    return _support.touch ? e.changedTouches[0] : e;
  };

  var _style = {
    transform                : _prefixStyle( "transform" ),
    transformOrigin          : _prefixStyle( "transformOrigin" ),
    transition               : _prefixStyle( "transition" ),
    transitionDuration       : _prefixStyle( "transitionDuration" ),
    transitionDelay          : _prefixStyle( "transitionDelay" ),
    transitionTimingFunction : _prefixStyle( "transitionTimingFunction" )
  };

  var self = null;

  var slide = function ( container, config ) {
    config || ( config = {} );
    var defaults = {
      container : container || "js-slide",
      ul        : ".slide-image",
      li        : "li",
      autoTime  : 5
    };

    for(var i in defaults) defaults.hasOwnProperty(i) && !config.hasOwnProperty(i) && ( config[i] = defaults[i] );

    this.config = config;

    self = this;

    this.init();
  };
  
  // 初始化
  slide.prototype.init = function() {

    var c = this.config;

    this.container = ( typeof c.container === "string" ) ? document.getElementById( c.container ) : c.container;
    this.ul = this.container.querySelector( c.ul );
    this.li = this.ul.querySelectorAll ( c.li );

    this.index = 0;
    this.length = this.li.length;
    this.width = this.container.offsetWidth;

    [].forEach.call(this.li, function( item, index ) {
      item.style[_style.transform] = getTranslate( index * self.width );
    });

    this.createControl();

    this.config.autoTime && this.autoPlay();

    this.bindTouch();
  };

  // 创建指示点点点
  slide.prototype.createControl = function() {

    this.control = document.createElement( "ul" );
    this.control.setAttribute( "class", "slide-number" );

    var html = "";
    [].forEach.call(this.li, function( item, index ) {
      var className = index === self.index ? "current" : "";
      html += "<li class='" + className + "'></li>";
    });

    this.control.innerHTML = html;
    this.container.appendChild( this.control );
  };

  // 监听滑动事件
  slide.prototype.bindTouch = function() {
    var c = this.container;
    c.addEventListener(_e.start, this.eventStart, false);
    c.addEventListener(_e.move, this.eventMove, false);
    c.addEventListener(_e.end, this.eventEnd, false);
    c.addEventListener(_e.cancel, this.eventEnd, false);
  };

  // 自动播放
  slide.prototype.autoPlay = function() {

    var autoTime = this.config.autoTime * 1000;

    this.swipeDirection = "left";

    this.auto = setInterval(function(){
      self.index++;
      self.moveTo(true);
    }, autoTime);

  };

  slide.prototype.eventStart = function( e ) {

    clearInterval( self.auto );

    var touch = getEvent( e );
    self.startX = touch.pageX;
    self.startY = touch.pageY;
    self.move = true;
  };

  slide.prototype.eventMove = function( e ) {

    if ( !self.move ) return;

    var touch = getEvent( e ),
        x = touch.pageX - self.startX,
        y = touch.pageY - self.startY,
        index = self.index,
        len = self.length;

    // 记录滑动的方向
    // 从开始滑动到结束只记录一次，防止滑动的时候改变方向
    // 滑动结束以后才重新记录
    var swipeDirection = self.swipeDirection || "";

    if ( !self.recordDirection ) {
      // 判断移动方向
      if ( Math.abs(x) > Math.abs(y) ) {
        e.preventDefault();
        swipeDirection = x > 0 ? "right" : "left";
      } else {
        self.move = false;
        return;
      };
      self.recordDirection = true;
    };

    // 移动位移
    self.translateX = x;
    self.swipeDirection = swipeDirection;

    self.moveTo();

  };

  slide.prototype.eventEnd = function( e ) {
	  if ( self.move ) {
	    var x = self.translateX,
        len = self.length,
        index = self.index;

	    if ( Math.abs(x) >= self.width / 3 ) {
	      x > 0 ? index-- : index++;
	      self.changeIndex = true;
	    } else {
	      self.changeIndex = false;
	    };

	    self.translateX = 0;
	    self.index = index;
	    self.recordDirection = false;

	    self.moveTo( true );
	    self.move = false;
	    
	    self.autoPlay();
	  }
  };

  slide.prototype.moveTo = function( moveEnd ) {

    ( this.index < 0 ) && ( this.index = this.length - 1 );
    ( this.index >= this.length ) && ( this.index = 0 );

    this.changeIndex === undefined && ( this.changeIndex = true );

    var nowIndex = this.index,
        len = this.length,
        width = this.width,
        changeIndex = this.changeIndex,
        preIndex = nowIndex - 1,
        nextIndex = nowIndex + 1,
        x = this.translateX || 0;

    if ( nowIndex === 0 ) {
      preIndex = this.length - Math.abs(preIndex);
    };

    if ( nowIndex === len - 1 ) {
      nextIndex = nextIndex - this.length;
    };

    this.li[nowIndex].style[_style.transitionDuration] = moveEnd ? "500ms" : "0";
    
    if ( this.swipeDirection === "right" ) {
      
      this.li[preIndex].style[_style.transitionDuration] = changeIndex ? "0" : "500ms";
      this.li[nextIndex].style[_style.transitionDuration] = moveEnd ? "500ms" : "0";

    };

    if ( this.swipeDirection === "left" ) {

      this.li[preIndex].style[_style.transitionDuration] = moveEnd ? "500ms" : "0";
      this.li[nextIndex].style[_style.transitionDuration] = changeIndex ? "0" : "500ms";
      
    };

    var arr = [ this.li[preIndex], this.li[nowIndex], this.li[nextIndex] ];

    arr.forEach(function( item, index ) {
      item.style[_style.transform] = getTranslate( (index - 1) * width + x );
    });

    // 点点点指示
    var controlChild = this.control.children;
    [].forEach.call(controlChild, function( item, index ) {
      item.classList.remove( "current" );
    });
    controlChild[nowIndex].classList.add( "current" );

    this.changeIndex = true;

  };
  
  // 外部调用
  return function( container, config ) {
    new slide (container, config);
  };

});